昨天我們透過手動下 docker build
來進行多架構 Docker Image 編譯
但身為懶人的我,肯定是要自動化的吧
所以今天就要來介紹如何透過 CI/CD 來達成這件事啦
這裡會使用 GitLab CI 來實作
據說 GitLab CI 的執行環境是 x86_64 的 Docker 環境
所以說,如果是編譯 Docker Image 的話,預設會是編譯出 amd64 架構的 Docker Image如果像是 Kubernetes 這種「容器化應用」的管理系統是安裝在 arm64 平台上的話
那 GitLab CI 預設編譯出來的 amd64 架構的 Docker Image 會是不能運行的喔~(小聲說,之所以會寫編譯多架構 Docker Image 也是因為在 GitLab CI 這邊踩了坑😂)
官方文件:GitLab CI 描述文件,.gitlab-ci.yml
https://docs.gitlab.com/ee/ci/yaml/
我們可以看到,GitLab 官方列出來的 CI pipeline Global Keywords (下圖)
▲ 圖取自 GitLab Documentation
我們在這邊會用到的 Keywords 是 stages
,用來定義在這個 pipeline 中總共會有哪些階段
在這邊,我們主要會有兩個 pipeline 階段
# Pipelines 中的所有執行階段
stages:
# 編譯 Go source code
- build-source-code
# 編譯多架構 Docker Image
- build-docker-image
# 編譯 Go source code
build-code:
# 執行階段
stage: build-source-code
# 要使用的 docker image
image: golang:latest
# 執行 Job 前要做的事
before_script:
# 檢查 go 的版本
- go version
- export GO111MODULE=on
- export GIN_MODE=release
# 建立 it15th 資料夾
- mkdir -p ${CI_PROJECT_DIR}/
script:
- go build -o ${CI_PROJECT_DIR}/
# 透過 Docker-in-Docker 打包 Docker Image
build-image:
# 執行階段
stage: build-docker-image
# 宣告區域變數
variables:
# Docker Image 名稱
IMAGE_NAME: it15th
# 要使用的 docker image
image: docker:latest
# 要使用的服務
services:
- docker:dind
# 執行 Job 前要做的事
before_script:
# 查看 docker buildx 的版本
- docker buildx version
# 查看 docker buildx 有哪些架構可以用
- docker buildx inspect --bootstrap
# 登入 Docker Hub
- echo "$DOCKERHUB_PWD" | docker login -u $DOCKERHUB_USERNAME --password-stdin
script:
# 建立一個 docker buildx builder 實例
# 使用 docker-container driver 並使用這個 builder 實例
- docker buildx create --name it15thBuilder --driver docker-container --use
# 透過上面建出來的 builder 不使用快取來編譯多架構 Docker Image
# 預設使用 Dockerfile 來編譯
# 指定系統架構為 linux/amd64、linux/arm64
# 編譯完成後加上 latest tag 推上 Docker Hub
- docker buildx build --push --no-cache -t $DOCKERHUB_USERNAME/$IMAGE_NAME:latest $CI_PROJECT_DIR/ --platform linux/amd64,linux/arm64
# 上傳到 Docker Hub 後移除 it15thBuilder 這個 builder 實例
- docker buildx rm it15thBuilder
我們的 .gitlab-ci.yml
最終就會變成下面這樣啦
# Pipelines 中的所有執行階段
stages:
# 編譯 Go source code
- build-source-code
# 透過 Docker-in-Docker 打包多架構 Docker Image
- build-docker-image
# 編譯 Go source code
build-code:
# 執行階段
stage: build-source-code
# 要使用的 docker image
image: golang:latest
# 執行 Job 前要做的事
before_script:
# 檢查 go 的版本
- go version
- export GO111MODULE=on
- export GIN_MODE=release
# 建立 it15th 資料夾
- mkdir -p ${CI_PROJECT_DIR}/
script:
- go build -o ${CI_PROJECT_DIR}/
# 透過 Docker-in-Docker 打包 Docker Image
build-image:
# 執行階段
stage: build-docker-image
# 宣告區域變數
variables:
# Docker Image 名稱
IMAGE_NAME: it15th
# 要使用的 docker image
image: docker:latest
# 要使用的服務
services:
- docker:dind
# 執行 Job 前要做的事
before_script:
# 查看 docker buildx 的版本
- docker buildx version
# 查看 docker buildx 有哪些架構可以用
- docker buildx inspect --bootstrap
# 登入 Docker Hub
- echo "$DOCKERHUB_PWD" | docker login -u $DOCKERHUB_USERNAME --password-stdin
script:
# 建立一個 docker buildx builder 實例
# 使用 docker-container driver 並使用這個 builder 實例
- docker buildx create --name it15thBuilder --driver docker-container --use
# 透過上面建出來的 builder 不使用快取來編譯多架構 Docker Image
# 預設使用 Dockerfile 來編譯
# 指定系統架構為 linux/amd64、linux/arm64
# 編譯完成後加上 latest tag 推上 Docker Hub
- docker buildx build --push --no-cache -t $DOCKERHUB_USERNAME/$IMAGE_NAME:latest $CI_PROJECT_DIR/ --platform linux/amd64,linux/arm64
# 上傳到 Docker Hub 後移除 it15thBuilder 這個 builder 實例
- docker buildx rm it15thBuilder
透過 GitLab CI 自動化編譯多架構 Docker Image
成功讓我們可以不用手動輸入 docker build
編譯
這樣日後就只要將 Code Commit 到 Git Repo 後,就會自動透過 GitLab CI 開始編譯多架構 Docker Image 了
明天就要來將編譯好的 Docker Image 透過 Kubernetes 來執行啦
明天見~